#!/bin/bash -e

# Date 		: 2021.1.25
# Author	: majin
# Mail 		: xx
# Function	: easy to collect data for func sort 
# Version 	: 1.0
# Update 	: 2021.1.25

RES="\033[0m"
GREEN="\033[32m"
BLUE="\033[36m"
YELLOW="\033[33m"
PURPLE="\033[35m"
RED="\033[31m"

name_msg(){ echo -e "${GREEN}name_msg:  [ `readlink -f $0` ] ${RES}";}
info_msg(){ echo -e "${BLUE}$1 ${RES}";}
warn_msg(){ echo -e "${PURPLE}$1 ${RES}";}

type -p "pigz" && GZIP=pigz || GZIP=gzip

set -- $(getopt -q e:f:ho:p:r "$@")
YOUR_BINARY=""
YOUR_PERF_DATA=""
YOUR_PID=""
YOUR_OUTPUT=""
run_binary=""
while [ -n "$1" ]
do
  case "$1" in
  -r) 
    run_binary="r"
    info_msg "will run perf record for Applications"
    shift ;;
  -e) YOUR_BINARY=`echo $2 |sed "s/'//g"`
    info_msg "YOUR_BINARY: ${YOUR_BINARY}"
    shift ;;
  -f) YOUR_PERF_DATA="$2"
    info_msg "YOUR_PERF_DATA: ${YOUR_PERF_DATA}"
    shift ;;
  -p) YOUR_PID="$2"
    info_msg "YOUR_PID: ${YOUR_PID}"
    shift ;;
  -o) YOUR_OUTPUT="$2"
    info_msg "YOUR_OUTPUT: ${YOUR_OUTPUT}"
    shift ;;
  -h) 
    info_msg "usage: $0  -e YOUR_BINARY -p perf.data -o OUTPUT_NAME"
    info_msg "this need input binary and perf.data, output for func sort"
    info_msg "for perf.data:"
    info_msg "  For Applications: "
    info_msg "    perf record -BN -F 3999 --no-buffering -g -e instructions:u -o perf.data -- YOUR_BINARY"    
    info_msg "  For Services: this need to extra input the YOUR_PID by \"-p YOUR_PID\", so record that when Services running"
    info_msg "    perf record -BN -F 3999 --no-buffering -g -p YOUR_PID -e instructions:u -o perf.data -- sleep SLEEP_TIME"
    info_msg "    or"
    info_msg "    perf record -BN -F 3999 --no-buffering -g -a -e instructions:u -o perf.data -- sleep SLEEP_TIME"
    exit;;
  --) shift
    break ;;
   *) echo "$1 is not option";;
esac
  shift
done

if [[ ! ${YOUR_BINARY} ]];then
  warn_msg "YOUR_BINARY is NONE, please add \`-e YOUR_BINARY\`"
  exit
fi

if [[ ! ${YOUR_PERF_DATA} ]];then
  info_msg "YOUR_PERF_DATA is NONE, set it whit perf.data, or add \`-f YOUR_PERF_DATA\`"
  YOUR_PERF_DATA="perf.data"
fi

if [[ "r" == ${run_binary} ]];then
  info_msg "run perf record -BN -F 3999 --no-buffering -g -e instructions:u -o ${YOUR_PERF_DATA} -- ${YOUR_BINARY}"
  perf record -BN -F 3999 --no-buffering -g -e instructions:u -o ${YOUR_PERF_DATA} -- ${YOUR_BINARY} 
fi

# perf record -BN -F 3999 --no-buffering -g -a -e instructions:u -o perf.data -- sleep ${SLEEP_TIME:-200}
# perf record -BN -F 3999 --no-buffering -g -p ${YOUR_PID} -e instructions:u -o perf.data -- sleep ${SLEEP_TIME:-200}
# perf record -BN -F 3999 --no-buffering -g -e instructions:u -o perf.data ./${exe_name}
# --call-graph dwarf 

# perf_pid=`$(jobs -p)`
# echo "perf_pid: ${perf_pid}"
    
# sleep 1

# # ps -ef | grep "mysqld" | grep -v grep | awk '{print $2}'
# exe_pid=${exe_pid:-$(pgrep -o "${exe_name}")}
# echo "exe_pid: ${exe_pid}"

# if [[ -z $exe_pid ]] ; then
#     echo "Error getting EXE PID"
#     exit 1
# fi

# echo "wait for perf"
# wait $perf_pid

if [[ ${YOUR_PID} ]];then
  info_msg "script ${YOUR_PERF_DATA} whit pid: ${YOUR_PID}"
  info_msg "perf script -i ${YOUR_PERF_DATA} --fields comm,pid,ip | sed -ne "/^[^   ]\+[   ]*${YOUR_PID}[   ]*\$/,+2p" | $GZIP -c > ${YOUR_BINARY}.perf.pds.gz"

  perf script -i ${YOUR_PERF_DATA} --fields comm,pid,ip | sed -ne \"/^[^   ]\+[   ]*${YOUR_PID}[   ]*\$/,+2p\" | $GZIP -c > ${YOUR_BINARY}.perf.pds.gz
else
  info_msg "script ${YOUR_PERF_DATA} whit binary name: ${YOUR_BINARY}"
  info_msg "perf script -i ${YOUR_PERF_DATA} --fields comm,pid,ip | sed -ne \"/^\w*${YOUR_BINARY}.*\$/,+2p\" | $GZIP -c > ${YOUR_BINARY}.perf.pds.gz"

  perf script -i ${YOUR_PERF_DATA} --fields comm,pid,ip | sed -ne "/^\w*${YOUR_BINARY}.*\$/,+2p" | $GZIP -c > ${YOUR_BINARY}.perf.pds.gz
fi

# perf script -i perf.data --fields comm,pid,ip | sed -ne "/^[^   ]\+[   ]*${YOUR_PID}[   ]*\$/,+2p" | $GZIP -c > ${YOUR_BINARY}.perf.pds.gz
# perf script -i perf.data --fields comm,pid,ip | sed -ne "/^\w*${YOUR_BINARY}.*\$/,+2p" | $GZIP -c > ${YOUR_BINARY}.perf.pds.gz
# perf script -i perf.data --fields comm,pid,ip | sed -ne "/^[${exe_name}]\+[   ]*${YOUR_PID}[   ]*\$/,+2p" | $GZIP -c > ${YOUR_BINARY}.perf.pds.gz

info_msg "creat func symbols addr, which will be use to build callgraph"
nm -S ${YOUR_BINARY} > ${YOUR_BINARY}.nm

# pushd $TMPDIR/..

# TARFILE=${TMPDIR}.tgz

# tar cvzf $TARFILE `basename $TMPDIR`

# popd

# echo "Generated file $TARFILE"
